/*
 * SysCall.h
 *
 *  Created on: Jul 10, 2009
 *      Author: oferbart
 */

#ifndef SYSCALL_H_
#define SYSCALL_H_

#include <iostream>
#include <stdio.h>
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
#include <vector>
#include <sstream>
#include "Utils.h"
#include "MetadataBlock.h"
#include "INode.h"
#include "BlockNode.h"
#include "Utils.h"
#include "Log.h"
#include "HD.h"
#include "Directory.h"
#include <utility>
#include <math.h>
#include "OpenFileTable.h"
using namespace std;

#define LASTISAFILE 1
#define LASTISASOFTLINK 2
#define LASTISADIR 3
#define NOCHECK 4

class SysCall {
private:
	OpenFileTable* _openFileTable;
	FileSys* _fs;

	vector<pair<int,string> >* getPairListOfPath(char* fileName, bool processLast, int typeOfLast);
	string getLastNameInPath(char* fileName);
	char* getSoftLinkAddress(int inode);
	int setSoftLinkAddress(int inode, char* path);
	bool isOpen(int i_inodeNum);

public:

	SysCall(FileSys* fs);
	virtual ~SysCall();

	// creates and opens a new file named ‘file_name’ returning a fd to the new file.
	// If type is soft-link mark it as such. Opens the file with the specified permissions.
	int MakeFile(char* fileName, int type, int accessPermissions);

	int MakeFile(char* fileName, int accessPermissions);

	int MakeSoftLink(char* targetFileName, char* softLinkFileName, int accessPermissions);

	// creates a hard link with name file-name, linked to target.
	/// returns 0 on success.
	int MakeHLink(char* targetFileName, char* fileName);

	int ConnectSoftLink(char* targetFileName, char* softLinkfileName);

	// creates a new directory named ‘dir-name’.
	/// returns 0 on success.
	int MakeDir(char* dirName);

	// removes the directory ‘dir-name’.
	/// returns 0 on success.
	int RmDir(char* dirName);

	// removes the file ‘file-name’.
	/// returns 0 on success.
	int RmFile(char* fileName);

	// lists the content of the location-directory. Return list in buf.
	/// returns 0 on success.
	int ls(char* dirName, char* buf);

	vector<pair<string, int> >* lsVector(char* dirName);

	// opens the file ‘file-name’. Needs to deal with soft-links.
	// opens the file with the specified permissions.
	/// returns fd or -1 on failure.
	int Open(char* fileName, int accessPermissions);

	// closes the entry of the file in the file table, and frees the entry in the fd table.
	/// returns 0 on success.
	int Close(int fd);

	// moves the file curser to ‘location’.
	/// returns 0 on success.
	int Seek(int fd, int location);

	// reads nBytes from the received file into the buffer.
	/// returns number of bytes read.
	int Read (int fd, int nBytes, unsigned char* buffer);

	// writes nBytes from buffer into the file.
	/// returns number of bytes written.
	int Write (int fd, int nBytes, unsigned char* buffer);

	// moves the file oldName to newName. This function allows moving files to
	// different directories and \ or change the files name.
	int moveFile(char* oldName, char* newName);

	// Returns whether this address is a directory or not. Needs to deal with soft-links.
	bool isDir(char * address);

	// locks file, so that only read operations are allowed.
	// There is no limit on the number of processes that are allowed to concurrently read the file.
	// No processes are allowed to write to the file if there is an open read lock on the file.
	// It is not obligatory to lock the file to read it.
	// You should not block if it is locked rather return an error.
	int lockRead(int fd);

	// locks file, so that only one process may hold the lock.
	// This process may write to the file, and no other files may write to it or read from it.
	// A child does not inherit this lock. It is not obligatory to lock the file to write to it.
	// You should not block if it is locked rather return an error
	int lockWrite(int fd);

	// releases the reading lock held by this process.
	// Only the process which locked the file may release the lock.
	int releaseLockRead(int fd);

	// releases the writing lock held by this process.
	// Only the process that locked the file may release this lock.
	int releaseLockWrite(int fd);

	int getSize(char* fileName);


};

#endif /* SYSCALL_H_ */
